#pragma once

#include<iostream>
#include<string>
#include<functional>
#include<pthread.h>
#include<unistd.h>
#include"Logger.hpp"
//获取lwp 需要系统调用
#include<sys/syscall.h>
#define get_lwp_id() syscall(SYS_gettid)

using func_t = std::function<void(const std::string& name)>;
const std::string threadnamedefault = "None-Name";

//线程所要提供的功能 -> 创建 、等待
class Thread
{
public:
    //_func 时所要执行的任务，需要外部传递进来
    Thread(func_t func , const std::string& name = threadnamedefault)
    :_name(name)
    ,_func(func)
    ,_is_running(false)
    {
        LOG(LogLevel::INFO) << _name << " 创建线程成功";

    }
    static void* start_routine(void* args)//因为成员函数的第一个参数默认为this 指针，而静态成员函数无法访问非静态成员方法、属性，故而此处采用传参的形式
    {
        //需要将任务、线程名……传递进来 --> 结构体 --> 将Thread 自己传递进入
        Thread* self = static_cast<Thread*>(args);
        self->_is_running = true;
        //填写信息、执行任务
        self->_lwpid = get_lwp_id();
        self->_func(self->_name);
        //退出
        pthread_exit((void*)0);
    }
    void Start()
    {
        //成功返回0，失败返回错误码
        int n = pthread_create(&_tid , nullptr , start_routine , this);
        if(n==0)
        {
            //使用日志打印
            LOG(LogLevel::INFO) << _name << " 创建线程成功";
        }
    }
    void Join()
    {
        if(!_is_running) return;
        
        int n = pthread_join(_tid , nullptr);

        if(n==0)
        { 
            LOG(LogLevel::INFO) << _name << " 等待线程成功";
        }
    }
    void Stop()
    {
        pthread_cancel(_tid);
    }
    ~Thread()
    {}
private:
    bool _is_running;
    //线程的基本属性：tip lwpid name 所要调用的函数
    pthread_t _tid;
    pid_t _lwpid;
    std::string _name;

    func_t _func;
};